package com.lsh.oms.core.records;

import com.lsh.base.lang.DateTimes;
import com.lsh.base.lang.Maps;
import com.lsh.base.lang.json.Jsons;
import com.lsh.oms.core.exception.BusinessException;
import com.lsh.oms.core.model.order.OrderHead;
import com.lsh.oms.core.proxy.service.PsiProxy;
import com.lsh.oms.core.records.core.Return;
import com.lsh.oms.core.service.order.OrderQueryService;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;

import static com.lsh.base.lang.BigDecimals.divideWithScale2;
import static com.lsh.base.lang.bean.Beans.*;

public class LossResult extends ReturnResultRecord {

    @Resource
    private PsiProxy psi;

    @Resource
    private OrderQueryService orders;

    @Override
    public void paymentNotify(Map<String, Object> request) {
        if (!"PENDING".equals(paymentStatus)) {
            throw BusinessException.invalidStatus();
        }
        BigDecimal amount = getBigDecimal(request, "amount");
        Integer paidAt = getInt(request, "paid_at");
        if (amount == null || paidAt == null) {
            throw BusinessException.badRequest();
        }
        this.status = Status.TERMINATED;
        this.paymentStatus = "SUCCESS";
        this.paymentPaidAt = DateTimes.of(paidAt);
        this.paymentAmount = amount;
        int affected = mapper.updatePayment(this);
        if (affected > 0) {
            issue(request);
        }
    }

    @Override
    public void run(Map<String, Object> request) {

        OrderHead orderInfo = orders.findByCode(orderId, false, false);

        Map<String, Object> form = new HashMap<>();
        form.put("warehouse_code", getString(ext, "return.warehouse.id"));
        form.put("order_id", id);
        form.put("so_order_id", orderId);
        form.put("customer_id", getString(ext, "user.uid"));
        form.put("customer_name", getString(ext, "user.username"));

        Integer damageType = (takeResponsibility == Responsibility.DELIVERYMAN)
                ? 1
                : (takeResponsibility == Responsibility.COMPANY) ? 2 : 3;

        form.put("damage_type", damageType);
        form.put("order_amount", amount.toString());

        form.put("owner_id", "1");
        form.put("vender_id", getString(orderInfo.extendedProperties(), "providerId", "0"));
        form.put("return_order_type", Return.Occasion.BEFORE_SIGN.name().equals(getString(ext, "return.occasion")) ? 1 : 2);

        form.put("ext", Jsons.toJsonString(Maps.newHashMap(
                "oms_return_order_id", returnId,
                "oms_return_id", returnId,
                "damage_type", damageType)));

        form.put("items", details.stream().map($ -> ((ReturnResultDetailRecord) $)).map($ -> Maps.of(
                "line_no", $.itemCode.toString(),
                "goods_id", getString($.ext, "goods.code"),
                "qty", ($.realQuantity()).toString(),
                "goods_amount", $.amount().toString(),
                "price", divideWithScale2($.price, $.saleUnit)))
                .collect(Collectors.toList()));

        psi.reportLoss(form, venderId);
    }
}
